package com.lframework.jh.push.manage.controller;

import com.lframework.jh.push.core.components.resp.InvokeResult;
import com.lframework.jh.push.core.components.resp.InvokeResultBuilder;
import com.lframework.jh.push.core.components.resp.PageResult;
import com.lframework.jh.push.core.controller.DefaultBaseController;
import com.lframework.jh.push.core.utils.CollectionUtil;
import com.lframework.jh.push.core.utils.ObjectUtil;
import com.lframework.jh.push.core.utils.PageResultUtil;
import com.lframework.jh.push.core.utils.StringUtil;
import com.lframework.jh.push.manage.bo.app.AppSelectorBo;
import com.lframework.jh.push.manage.bo.mch.MchSelectorBo;
import com.lframework.jh.push.manage.bo.menu.SysMenuSelectorBo;
import com.lframework.jh.push.manage.bo.role.SysRoleSelectorBo;
import com.lframework.jh.push.manage.bo.user.SysUserSelectorBo;
import com.lframework.jh.push.service.entity.App;
import com.lframework.jh.push.service.entity.Mch;
import com.lframework.jh.push.service.entity.SysMenu;
import com.lframework.jh.push.service.entity.SysRole;
import com.lframework.jh.push.service.entity.SysUser;
import com.lframework.jh.push.service.service.AppService;
import com.lframework.jh.push.service.service.MchService;
import com.lframework.jh.push.service.service.SysMenuService;
import com.lframework.jh.push.service.service.SysRoleService;
import com.lframework.jh.push.service.service.SysUserService;
import com.lframework.jh.push.service.vo.app.AppSelectorVo;
import com.lframework.jh.push.service.vo.mch.MchSelectorVo;
import com.lframework.jh.push.service.vo.menu.SysMenuSelectorVo;
import com.lframework.jh.push.service.vo.role.SysRoleSelectorVo;
import com.lframework.jh.push.service.vo.user.SysUserSelectorVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 数据选择器
 *
 * @author zmj
 */
@Api(tags = "数据选择器")
@Validated
@RestController
@RequestMapping("/selector")
public class SelectorController extends DefaultBaseController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private AppService appService;

    @Autowired
    private MchService mchService;

    /**
     * 系统菜单
     */
    @ApiOperation("系统菜单")
    @GetMapping("/menu")
    public InvokeResult<List<SysMenuSelectorBo>> menu(@Valid SysMenuSelectorVo vo) {

        List<SysMenuSelectorBo> results = CollectionUtil.emptyList();
        List<SysMenu> datas = sysMenuService.selector(vo);
        if (CollectionUtil.isNotEmpty(datas)) {
            results = datas.stream().map(SysMenuSelectorBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(results);
    }

    @ApiOperation("角色")
    @GetMapping("/role")
    public InvokeResult<PageResult<SysRoleSelectorBo>> role(@Valid SysRoleSelectorVo vo) {

        PageResult<SysRole> pageResult = sysRoleService.selector(getPageIndex(vo),
            getPageSize(vo), vo);
        List<SysRole> datas = pageResult.getDatas();
        List<SysRoleSelectorBo> results = null;
        if (CollectionUtil.isNotEmpty(datas)) {
            results = datas.stream().map(SysRoleSelectorBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
    }

    /**
     * 加载角色
     */
    @ApiOperation("加载角色")
    @PostMapping("/role/load")
    public InvokeResult<List<SysRoleSelectorBo>> loadRole(
        @RequestBody(required = false) List<String> ids) {

        if (CollectionUtil.isEmpty(ids)) {
            return InvokeResultBuilder.success(CollectionUtil.emptyList());
        }

        List<SysRole> datas = ids.stream().filter(StringUtil::isNotBlank)
            .map(t -> sysRoleService.findById(t))
            .filter(Objects::nonNull).collect(Collectors.toList());
        List<SysRoleSelectorBo> results = datas.stream()
            .map(SysRoleSelectorBo::new)
            .collect(
                Collectors.toList());

        return InvokeResultBuilder.success(results);
    }

    @ApiOperation("用户")
    @GetMapping("/user")
    public InvokeResult<PageResult<SysUserSelectorBo>> user(@Valid SysUserSelectorVo vo) {

        PageResult<SysUser> pageResult = sysUserService.selector(getPageIndex(vo),
            getPageSize(vo), vo);
        List<SysUser> datas = pageResult.getDatas();
        List<SysUserSelectorBo> results = null;

        if (!CollectionUtil.isEmpty(datas)) {
            results = datas.stream().map(SysUserSelectorBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
    }

    /**
     * 加载用户
     */
    @ApiOperation("加载用户")
    @PostMapping("/user/load")
    public InvokeResult<List<SysUserSelectorBo>> loadUser(
        @RequestBody(required = false) List<String> ids) {

        if (CollectionUtil.isEmpty(ids)) {
            return InvokeResultBuilder.success(CollectionUtil.emptyList());
        }

        List<SysUser> datas = ids.stream().filter(StringUtil::isNotBlank)
            .map(t -> sysUserService.findById(t))
            .filter(Objects::nonNull).collect(Collectors.toList());
        List<SysUserSelectorBo> results = datas.stream()
            .map(SysUserSelectorBo::new)
            .collect(
                Collectors.toList());

        return InvokeResultBuilder.success(results);
    }

    @ApiOperation("应用")
    @GetMapping("/app")
    public InvokeResult<PageResult<AppSelectorBo>> app(@Valid AppSelectorVo vo) {

        PageResult<App> pageResult = appService.selector(getPageIndex(vo),
            getPageSize(vo), vo);
        List<App> datas = pageResult.getDatas();
        List<AppSelectorBo> results = null;

        if (!CollectionUtil.isEmpty(datas)) {
            results = datas.stream().map(AppSelectorBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
    }

    /**
     * 加载应用
     */
    @ApiOperation("加载应用")
    @PostMapping("/app/load")
    public InvokeResult<List<AppSelectorBo>> loadApp(
        @RequestBody(required = false) List<String> ids) {

        if (CollectionUtil.isEmpty(ids)) {
            return InvokeResultBuilder.success(CollectionUtil.emptyList());
        }

        List<App> datas = ids.stream().filter(StringUtil::isNotBlank)
            .map(t -> appService.findById(t))
            .filter(Objects::nonNull).collect(Collectors.toList());
        List<AppSelectorBo> results = datas.stream()
            .map(AppSelectorBo::new)
            .collect(
                Collectors.toList());

        return InvokeResultBuilder.success(results);
    }

    @ApiOperation("商户")
    @GetMapping("/mch")
    public InvokeResult<PageResult<MchSelectorBo>> app(@Valid MchSelectorVo vo) {

        PageResult<Mch> pageResult = mchService.selector(getPageIndex(vo),
            getPageSize(vo), vo);
        List<Mch> datas = pageResult.getDatas();
        List<MchSelectorBo> results = null;

        if (!CollectionUtil.isEmpty(datas)) {
            results = datas.stream().map(MchSelectorBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
    }

    /**
     * 加载应用
     */
    @ApiOperation("加载商户")
    @PostMapping("/mch/load")
    public InvokeResult<List<MchSelectorBo>> loadMch(
        @RequestBody(required = false) List<Integer> ids) {

        if (CollectionUtil.isEmpty(ids)) {
            return InvokeResultBuilder.success(CollectionUtil.emptyList());
        }

        List<Mch> datas = ids.stream().filter(ObjectUtil::isNotNull)
            .map(t -> mchService.findById(t))
            .filter(Objects::nonNull).collect(Collectors.toList());
        List<MchSelectorBo> results = datas.stream()
            .map(MchSelectorBo::new)
            .collect(
                Collectors.toList());

        return InvokeResultBuilder.success(results);
    }
}
